#ifndef __ZHU_OS_KERNEL64_MM_H__
#define __ZHU_OS_KERNEL64_MM_H__
#include "types.h"
#include "bitmap.h"

#define PAGE_SIZE 4096

#define FOUR_LEVEL_HEAD_TABLE_ADDR 0x8000
#define FIRST_PDPT_ADDR 0x9000
#define FIRST_PDT_ADDR 0xa000

#define PML4_SHIFT 39
#define PDPT_SHIFT 30
#define PDT_SHIFT 21

#define INDEX_MASK 0x1FF

/*
在C语言中，`__attribute__((packed))`是GCC编译器的一个特殊标识，
表示结构体中的成员按照紧凑模式进行存储，取消了编译器默认的字节对齐方式，
可以减小结构体的大小。这样做主要是为了结构体在内存中的存储和访问效率。

例如：
```c
struct test {
    char a;
    int b;
} __attribute__((packed));
```
在这个例子中，不加`__attribute__((packed))`，因为编译器的对齐方式，`a`占用1个字节，
而`b`占用4个字节，但是它们之间可能会存在几个字节的空隙，所以整个结构体的大小可能大于5个字节。
如果加了`__attribute__((packed))`，那么就只会占用5个字节，`a`和`b`之间不会有空隙，
这样可以节省内存，特别是在嵌入式系统中，资源有限，这非常重要。

但是这样做可能会增加CPU的负担，因为CPU读取非对齐的内存会比读取对齐的内存慢。所以这是空间和时间的一个权衡。
*/
typedef struct {
    unsigned int base_addr_low;
    unsigned int base_addr_high;
    unsigned int length_low;
    unsigned int length_high;
    unsigned int type;
} __attribute__((packed)) check_memory_item_t;

typedef struct {
    unsigned short times;
    check_memory_item_t* data;
} __attribute__((packed)) check_memory_info_t;

typedef struct 
{
    uint addr_start;
    uint addr_end;
    uint valid_mem_size;
    uint pages_total;
    uint pages_free;
    uint pages_used;
} __attribute__((packed)) physics_memory_info_t;

typedef struct 
{
    uint addr_base;
    uint pages_total;
    bitmap_t bitmap;
    uchar* bitmap_buf;
} __attribute__((packed)) physics_memory_map_t;

void print_check_memory_info();

void phy_memory_init();

void* get_free_page();

void free_page(void* p);

void* kmalloc(size_t size);

void kfree_s(void* obj, int size);

// 将虚拟内存映射到指定的物理页
void physics_map_virtual_addr_2m(uint32_t addr, uint32_t phy_addr_base);

void physics_addr_map_virtual_addr_2m_2(uint64_t addr, uint32_t phy_addr_base, 
    uint16_t pdt_flag, uint16_t pdpt_flag);
#endif